package Misil.Comportamientos;

import Utilidades.CalculadoraDeMisiles;

/**
 * @brief Esta clase define el patron de comportamiento del misilAliado tras
 *        alcanzar los 100 metros de altura. Lo que hace es posicionarse para
 *        apuntar al enemigo y luego pasar al siguiente patron de
 *        comportamiento.
 * @author Marcelo
 * @version 1.0
 * @created 17-jul-2012 09:08:50 p.m.
 */
public class Posicionamiento implements ComportamientoMisilAliado {
	// Campos de la clase Posicionamiento
	private int tipoMovimiento = 2;
	private double[] objetivo;
	private double[] vectorVelocidad;

	/**
	 * @brief Constructor predeterminado
	 */
	public Posicionamiento() {
		vectorVelocidad = new double[3];
		vectorVelocidad[0] = 0;
		vectorVelocidad[1] = 0;
		vectorVelocidad[2] = 0;
		objetivo = new double[3];
		objetivo[0] = 0;
		objetivo[1] = 0;
		objetivo[2] = 0;
	}

	/**
	 * @brief Constructor alternativo
	 * @param objeto
	 *            objetivo a alcanzar. Puede ser un misil o un long[]
	 */
	public Posicionamiento(Object objeto, double[] posicion) {
		vectorVelocidad = new double[3];
		vectorVelocidad[0] = 0;
		vectorVelocidad[1] = 0;
		vectorVelocidad[2] = 0;
		objetivo = (double[]) objeto;
		calcularNuevoVectorDeVelocidad(posicion);
	}

	/**
	 * @brief Metodo que devuelve el tipo de movimiento actual de un determinado
	 *        "misil". (conceptualmente no seria del misil, pero bueno)
	 * @return tipo de movimiento del patron de comportamiento adoptado
	 *         actualmente.
	 */
	public int getTipoMovimiento() {
		return tipoMovimiento;
	}

	/**
	 * @brief funcion que establece el objetivo de este misil (un punto en el
	 *        espacio)
	 */
	public void setObjetivo(Object objeto) {
		objetivo = (double[]) objeto;
	}

	/**
	 * @brief Funcionq eu devuelve el valor del campo objetivo. Sirve para el
	 *        caso en el que un tipo de comportameito deba pasarle su objetivo a
	 *        otro.
	 * @return objetivo de este patron de comportamiento.
	 */
	public Object getObjetivo() {
		return objetivo;
	}

	/**
	 * @brief Metodo que establece un nuevo valor para el vector de velocidad
	 * @param vector
	 */
	public void setVectorDeVelocidad(double[] vector) {
		vectorVelocidad = vector;

	}

	/**
	 * @brief Funcion que devuelve el vector de velocidad del misil. Este vector
	 *        indica como se va a mover el misil en cada avance de tiempo y su
	 *        modulo es la velocidad del misil.
	 * @return vectorVelocidad del misil.
	 */
	public double[] getVectorDeVelocidad() {
		return vectorVelocidad;
	}

	/**
	 * @brief Funcion que calcula el nuevo vector de velocidad para alcanzar el
	 *        punto por donde el enemigo entra a la zona protegida.
	 * @param posicion
	 */
	private void calcularNuevoVectorDeVelocidad(double[] posicion) {
		CalculadoraDeMisiles calcu = new CalculadoraDeMisiles();
		vectorVelocidad = calcu.calcularNuevoVectorDeVelocidad(posicion,
				objetivo, 100);
	}

	/**
	 * @brief Funcion que verifica si se alcanzo el objetivo
	 * @return {@code true} si se alcanzo al objetivo {@code false} si aun no se
	 *         ha alcanzado al objetivo.
	 */
	public boolean objetivoAlcanzado(double[] posicion) {
		double distancia[] = new double[3];
		distancia[0] = objetivo[0] - posicion[0];
		distancia[1] = objetivo[1] - posicion[1];
		distancia[2] = objetivo[2] - posicion[2];
		double modulo = Math.sqrt(distancia[0] * distancia[0] + distancia[1]
				* distancia[1] + distancia[2] * distancia[2]);
		modulo = CalculadoraDeMisiles.redondear(modulo, 2);
		// System.out.println("Modulo de la distancia: "+modulo);
		if (modulo < 200) {
			System.out.println("OBJETIVO ALCANZADO!");
			return true;
		} else
			return false;
	}

	/**
	 * @brief No hace nada. Es para cumplir con la interface
	 */
	public double[] invertirVelocidad(double[] velocidad) {
		return null;
	}

}